#ifndef	__BFX_REF_XMLREADER_H__
#define	__BFX_REF_XMLREADER_H__

#include "XMLError.h"
#include "XMLNodeType.h"

namespace BFX
{

class REFNameTable;
class REFXMLSchemaInfo;
class REFXMLTextReaderImpl;

#ifdef	BFX_DLL_BUILD
template class BFX_API REF<REFUniStringBuilder>;
#endif

//////////////////////////////////////////////////////////////////////////////

// Specifies the state of the XmlReader.
enum ReadState
{
	// The Read method has not been called yet.
	ReadState_Initial      = 0,
	// Reading is in progress.
	ReadState_Interactive  = 1,
	// An error occurred that prevents the XmlReader from continuing.
	ReadState_Error        = 2,
	// The end of the stream has been reached successfully.
	ReadState_EndOfFile    = 3,
	// The Close method has been called and the XmlReader is closed.
	ReadState_Closed       = 4
};

// Specifies how entities are handled in REFXMLTextReader.
enum XMLEntityHandling
{
	// Expand all entities. This is the default in validating reader. No nodes with NodeType_EntityReference will be returned. 
	// The entity text is expanded in place of the entity references.
	XMLEntityHandling_ExpandEntities      = 1,

	// Expand character entities only and return general entities as nodes (NodeType=XmlNodeType_EntityReference, Name=the name of the entity).
	// Default in XmlTextReader. You must call ResolveEntity to see what the general entity expands to.
	XMLEntityHandling_ExpandCharEntities  = 2,
};

//////////////////////////////////////////////////////////////////////////////

// This class represent a XML pull parse.
class BFX_API REFXMLReader : public REFObject
{
	friend class REFXMLLoader;
public:
	virtual ~REFXMLReader() {}

	// Get the type of the current node.
	virtual XMLNodeType GetNodeType() const = 0;
	// Gets the name of the current node, including the namespace prefix.
	virtual UniString GetName() const;

	// Gets the name of the current node without the namespace prefix.
	virtual UniString GetLocalName() const = 0;
	// Gets the namespace URN (as defined in the W3C Namespace Specification) of the current namespace scope.
	virtual UniString GetNamespaceURI() const = 0;
	// Gets the namespace prefix associated with the current node.
	virtual UniString GetPrefix() const = 0;

	// Gets a value indicating whether
	virtual bool HasValue() const = 0;
	// Gets the text value of the current node.
	virtual UniString GetValue() const = 0;

	// Gets the base URI of the current node.
	virtual UniString GetBaseURI() const = 0;
	// Gets a value indicating whether the current node is an empty element (for example, <MyElement/>).
	virtual bool IsEmptyElement() const = 0;
	
	// Gets a value indicating whether the current node is an attribute that was generated from the default value defined in the DTD or schema.
	virtual bool IsDefault() const;

	// Gets the xml-nametable associated with the xmlreader.
	virtual REFNameTable* GetNameTable() const = 0;

	// Moving through the stream
	// Reads next node from the input data
	virtual bool Read() = 0;

	// Closes the stream, changes the ReadState to Closed, and sets all the properties back to zero/empty string.
	virtual void Close() = 0;

	// Returns the read state of the XmlReader.
	virtual ReadState GetReadState() const = 0;

	// If on attribute, moves to the element that contains the attribute node
	virtual bool MoveToElement() = 0;
	// Moves to the first attribute of the current node
	virtual bool MoveToFirstAttribute() = 0;
	// Moves to the next attribute of the current node
	virtual bool MoveToNextAttribute() = 0;
	// Moves to an attribute at the specified index (position)
	virtual void MoveToAttribute(int i) = 0;
	// Moves to an attribute with the specified Name
	virtual bool MoveToAttribute(const UniString& strName) = 0;
	// Moves to an attribute with the specified LocalName and NamespceURI
	virtual bool MoveToAttribute(const UniString& strLocalName, const UniString& strNamespaceURI) = 0;

	// Parses the attribute value into one or more Text and/or EntityReference node types.
	virtual bool ReadAttributeValue() = 0;

	virtual const XMLErrorContext& GetLastError() const	= 0;
	virtual bool IsErrorOccurred() const = 0;

protected:
	virtual REFXMLSchemaInfo* GetDtdSchemaInfo() const = 0;
};

//////////////////////////////////////////////////////////////////////////////

class BFX_API REFXMLTextReader : public REFXMLReader
{
	friend class REFXMLDocument;
protected:
	REFXMLTextReader(REFUniTextReader* pTextReader, REFNameTable* pNameTable);
public:
	// Initializes a new instance of the REFXMLTextReader class with the specified text reader.
	REFXMLTextReader(REFUniTextReader* pTextReader);
	virtual ~REFXMLTextReader();

	// Get the type of the current node.
	virtual XMLNodeType GetNodeType() const;
	// Gets the name of the current node, including the namespace prefix.
	virtual UniString GetName() const;

	// Gets the name of the current node without the namespace prefix.
	virtual UniString GetLocalName() const;
	// Gets the namespace URN (as defined in the W3C Namespace Specification) of the current namespace scope.
	virtual UniString GetNamespaceURI() const;
	// Gets the namespace prefix associated with the current node.
	virtual UniString GetPrefix() const;

	// Gets a value indicating whether
	virtual bool HasValue() const;
	// Gets the text value of the current node.
	virtual UniString GetValue() const;

	// Gets the base URI of the current node.
	virtual UniString GetBaseURI() const;
	// Gets a value indicating whether the current node is an empty element (for example, <MyElement/>).
	virtual bool IsEmptyElement() const;

	// Gets a value indicating whether the current node is an attribute that was generated from the default value defined in the DTD or schema.
	virtual bool IsDefault() const;

	// Gets the xml-nametable associated with the xmlreader.
	virtual REFNameTable* GetNameTable() const;

	// Moving through the stream, reads next node from the input data.
	// Returns true if the next node was read successfully; false if there are no more nodes to read.
	virtual bool Read();

	// Closes the stream, changes the ReadState to Closed, and sets all the properties back to zero/empty string.
	virtual void Close();

	// Returns the read state of the XmlReader.
	virtual ReadState GetReadState() const;

		// If on attribute, moves to the element that contains the attribute node
	virtual bool MoveToElement();
	// Moves to the first attribute of the current node
	virtual bool MoveToFirstAttribute();
	// Moves to the next attribute of the current node
	virtual bool MoveToNextAttribute();
	// Moves to an attribute at the specified index (position)
	virtual void MoveToAttribute(int i);
	// Moves to an attribute with the specified Name
	virtual bool MoveToAttribute(const UniString& strName);
	// Moves to an attribute with the specified LocalName and NamespceURI
	virtual bool MoveToAttribute(const UniString& strLocalName, const UniString& strNamespaceURI);

	// Parses the attribute value into one or more Text and/or EntityReference node types.
	virtual bool ReadAttributeValue();

	virtual const XMLErrorContext& GetLastError() const;
	virtual bool IsErrorOccurred() const;

protected:
	virtual REFXMLSchemaInfo* GetDtdSchemaInfo() const;

	//
	// XmlTextReader 
	//
public:
	// Disables or enables support of W3C XML 1.0 Namespaces
	void SetSupportNamespaces(bool bSupportNamespaces);
	bool IsSupportNamespaces() const;

	bool IsNormalization() const;
	void SetNormalization(bool bNormalization);

	UniString GetEncoding() const;

	// Specifies whether general entities should be automatically expanded or not
	XMLEntityHandling GetEntityHandling() const;
	void SetEntityHandling(XMLEntityHandling entityHandling);

private:
	REFXMLTextReaderImpl*	m_pImplementation;
};

#ifdef	BFX_DLL_BUILD
template class BFX_API REF<REFXMLReader>;
#endif

}	//	namespace BFX

#endif	//	__BFX_REF_XMLREADER_H__
